home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Hot Mix 17
/
Hot Mix 17.iso
/
HM17_SGI
/
research
/
lib
/
t3d.pro
< prev
next >
Wrap
Text File
|
1997-07-08
|
6KB
|
205 lines
; $Id: t3d.pro,v 1.5 1997/01/15 03:11:50 ali Exp $
;
; Copyright (c) 1987-1997, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
PRO t3d, TRANSLATE = trans, SCALE = scale, ROTATE=rota, $
RESET = reset, PERSPECTIVE = pers, OBLIQUE = oblique, $
XYEXCH = xyexch, XZEXCH = xzexch, YZEXCH = yzexch, $
MATRIX = mat
;+
; NAME:
; T3D
;
; PURPOSE:
; Implement three-dimensional transforms.
;
; This routine accumulates one or more sequences of translation,
; scaling, rotation, perspective, and oblique transformations
; and stores the result in !P.T, the 3D transformation system variable.
; All the IDL graphic routines use this [4,4] matrix for output.
;
; CATEGORY:
; Graphics.
;
; CALLING SEQUENCE:
; T3D [, /RESET, TRANSLATE = T, SCALE = S, ROTATE = R, ... ]
;
; INPUTS:
; No non-keyword inputs.
;
; KEYWORDS:
; All inputs to T3D are in the form of keywords. Any, all, or none of
; the following keywords can be present in a call to T3D. The order of
; the input parameters does not matter.
;
; The transformation specified by each keyword is performed in the
; order of their descriptions below (e.g., if both TRANSLATE and
; SCALE are specified, the translation is done first):
;
; RESET: Set this keyword to reset the transformation to the default
; identity matrix.
;
; TRANSLATE: A three-element vector of the translations in the X, Y, and Z
; directions.
;
; SCALE: A three-element vector of scale factors for the X, Y, and Z
; axes.
;
; ROTATE: A three-element vector of the rotations, in DEGREES,
; about the X, Y, and Z axes. Rotations are performed in the
; order of X, Y, and then Z.
;
; PERSPECTIVE: Perspective transformation. This parameter is a scalar (p)
; that indicates the Z distance of the center of the projection.
; Objects are projected into the XY plane at Z=0, and the "eye"
; is at point [0,0,p].
;
; OBLIQUE: A two-element vector of oblique projection parameters.
; Points are projected onto the XY plane at Z=0 as follows:
; x' = x + z(d COS(a)), and y' = y + z(d SIN(a)).
; where OBLIQUE[0] = d, and OBLIQUE[1] = a.
;
; XYEXCH: Exchange the X and Y axes.
;
; XZEXCH: Exchange the X and Z axes.
;
; YZEXCH: Exchange the Y and Z axes.
;
; MATRIX: Input/Output, If supplied as a 4 x 4 matrix on input,
; MATRIX contains the starting transformation matrix.
; If supplied as either a non-zero scalar, or as a 4x4
; matrix, the result is returned in this parameter and
; !P.T is not modified.
;
; OUTPUTS:
; The 4 by 4 transformation matrix !P.T is updated with the
; resulting transformation, unless the keyword MATRIX is supplied,
; in which case the result is returned in MATRIX and !P.T is
; not affected.
; !P.T3D is NOT set, so for the transformations to have effect you
; must set !P.T3D = 1 (or set the T3D keyword in subsequent calls
; to graphics routines).
;
; COMMON BLOCKS:
; None.
;
; SIDE EFFECTS:
; !P.T is changed if the keyword MATRIX is not set.
;
; RESTRICTIONS:
; This routine implements general rotations about the three axes.
; The routines SURFACE and SHADE_SURF may only be used in conjunction
; with T3D rotations that project the Z axis in 3 dimensions to
; a line parallel to the Y axis in 2 dimensions.
;
; PROCEDURE:
; This program follows that of Foley & Van Dam, "Fundamentals of
; Interactive Computer Graphics", Chapter 8, "Viewing in Three
; Dimensions".
;
; The matrix notation is reversed from the normal IDL sense,
; i.e., here, the first subscript is the column, the second is the row,
; in order to conform with the above reference.
;
; A right-handed system is used. Positive rotations are COUNTER-
; CLOCKWISE when looking from a positive axis to the origin.
;
; EXAMPLES:
; To reset the transformation, rotate 30 degs about the X axis
; and do perspective transformation with the center of the projection
; at Z = -3, X=0, and Y=0, enter:
;
; T3D, /RESET, ROT = [ 30,0,0], PERS = 3.
;
; Transformations may be cascaded, for example:
;
; T3D, /RESET, TRANS = [-.5,-.5,0], ROT = [0,0,45]
; T3D, TRANS = [.5,.5,0]
;
; The first command resets, translates the point [.5,.5,0] to the
; center of the viewport, then rotates 45 degrees counterclockwise
; about the Z axis. The second call to T3D moves the origin back to
; the center of the viewport.
;
; MODIFICATION HISTORY:
; DMS, Nov, 1987.
;
; DMS, June 1990. Fixed bug that didn't scale or translate
; matrices with perspective properly.
; DMS, July, 1996. Added MATRIX keyword.
;-
on_error,2 ;Return to caller if an error occurs
id = fltarr(4,4) ;Make identity matrix
for i=0,3 do id[i,i]= 1.0
if keyword_set(reset) then a = id $ ; Start from identity?
else if n_elements(mat) eq 16 then a = mat $ ;Use given transform
else a = !p.t ;Use existing transform
if n_elements(trans) ne 0 then begin ;Translate?
ri = id
for i=0,2 do ri[3,i] = trans[i]
a = a # ri ;Apply translation
endif
if n_elements(scale) ne 0 then begin ;Scale
ri = id
for i=0,2 do ri[i,i] = scale[i]
a = a # ri ;Apply scale
endif
if n_elements(rota) ne 0 then begin ;Rotate?
ri = id[0:2,0:2] ;Use 3 by 3's
r = ri
sx = sin(rota/!radeg) & cx = cos(rota/!radeg)
if rota[0] ne 0.0 then begin ;X Angle
r[1,1] = cx[0] & r[1,2] = sx[0]
r[2,1] = -sx[0] & r[2,2] = cx[0]
endif
if rota[1] ne 0 then begin ;Y angle
rr = ri
rr[0,0] = cx[1] & rr[0,2] = -sx[1]
rr[2,0] = sx[1] & rr[2,2] = cx[1]
r = r # rr
endif
if rota[2] ne 0 then begin ;Z angle
rr = ri
rr[0,0]= cx[2] & rr[0,1] = sx[2]
rr[1,0] = -sx[2] & rr[1,1] = cx[2]
r = r # rr
endif
rr = fltarr(4,4)
rr[0,0] = r & rr[3,3]=1.0
a = a # rr ;Apply cumulative rot transforms
endif
if n_elements(pers) ne 0 then begin ;Perspective?
r = id
r[2,3] = -1./pers
a = a # r
endif
if n_elements(oblique) ne 0 then begin ;Oblique projection?
r = id
r[2,2]=0.0
r[2,0] = oblique[0] * cos(oblique[1]/ !radeg)
r[2,1] = oblique[0] * sin(oblique[1]/ !radeg)
a = a # r
endif
if keyword_set(xyexch) then exch = [0,1] ;Code to exchange axes.
if keyword_set(xzexch) then exch = [0,2]
if keyword_set(yzexch) then exch = [1,2]
if n_elements(exch) ne 0 then begin ;Exchange axes.
t = a[exch[0],*]
a[exch[0],0] = a[exch[1],*]
a[exch[1],0] = t
endif
if KEYWORD_SET(mat) then mat = a $ ;Save final projection
else !p.t = a
end